package services

import (
	"bufio"
	"context"
	"encoding/json"
	"fmt"
	"io"
	"log"
	"os/exec"
	"strings"
	"sync"
	"time"
)

// MCPClient MCP客户端
type MCPClient struct {
	cmd    *exec.Cmd
	stdin  io.WriteCloser
	stdout io.ReadCloser
	reader *bufio.Reader
	mutex  sync.Mutex
	isInit bool
}

// MCPRequest MCP请求结构
type MCPRequest struct {
	JSONRPC string                 `json:"jsonrpc"`
	ID      interface{}            `json:"id"`
	Method  string                 `json:"method"`
	Params  map[string]interface{} `json:"params,omitempty"`
}

// MCPResponse MCP响应结构
type MCPResponse struct {
	JSONRPC string      `json:"jsonrpc"`
	ID      interface{} `json:"id"`
	Result  interface{} `json:"result,omitempty"`
	Error   *MCPError   `json:"error,omitempty"`
}

// MCPError MCP错误结构
type MCPError struct {
	Code    int    `json:"code"`
	Message string `json:"message"`
}

// NewMCPClient 创建新的MCP客户端
func NewMCPClient() *MCPClient {
	return &MCPClient{}
}

// Start 启动MCP服务器
func (c *MCPClient) Start() error {
	c.mutex.Lock()
	defer c.mutex.Unlock()

	if c.cmd != nil {
		log.Printf("[MCP-CLIENT] ℹ️ MCP服务器已经启动")
		return nil // 已经启动
	}

	log.Printf("[MCP-CLIENT] 🚀 启动MCP服务器进程...")

	// 启动MCP服务器进程
	c.cmd = exec.Command("./mcpserver/mcpserver")
	
	stdin, err := c.cmd.StdinPipe()
	if err != nil {
		log.Printf("[MCP-CLIENT] ❌ 创建stdin管道失败: %v", err)
		return fmt.Errorf("创建stdin管道失败: %v", err)
	}
	c.stdin = stdin

	stdout, err := c.cmd.StdoutPipe()
	if err != nil {
		log.Printf("[MCP-CLIENT] ❌ 创建stdout管道失败: %v", err)
		return fmt.Errorf("创建stdout管道失败: %v", err)
	}
	c.stdout = stdout
	c.reader = bufio.NewReader(stdout)

	// 启动进程
	if err := c.cmd.Start(); err != nil {
		log.Printf("[MCP-CLIENT] ❌ 启动MCP服务器失败: %v", err)
		return fmt.Errorf("启动MCP服务器失败: %v", err)
	}

	log.Printf("[MCP-CLIENT] ✅ MCP服务器进程启动成功，PID: %d", c.cmd.Process.Pid)

	// 初始化MCP服务器
	log.Printf("[MCP-CLIENT] 🔧 初始化MCP服务器...")
	if err := c.initialize(); err != nil {
		log.Printf("[MCP-CLIENT] ❌ 初始化MCP服务器失败: %v", err)
		c.Stop()
		return fmt.Errorf("初始化MCP服务器失败: %v", err)
	}

	c.isInit = true
	log.Printf("[MCP-CLIENT] ✅ MCP客户端启动成功")
	return nil
}

// Stop 停止MCP服务器
func (c *MCPClient) Stop() error {
	c.mutex.Lock()
	defer c.mutex.Unlock()

	if c.cmd == nil {
		return nil
	}

	if c.stdin != nil {
		c.stdin.Close()
	}
	if c.stdout != nil {
		c.stdout.Close()
	}

	if c.cmd.Process != nil {
		c.cmd.Process.Kill()
	}
	c.cmd.Wait()
	c.cmd = nil
	c.isInit = false

	log.Println("MCP客户端已停止")
	return nil
}

// initialize 初始化MCP服务器
func (c *MCPClient) initialize() error {
	req := MCPRequest{
		JSONRPC: "2.0",
		ID:      1,
		Method:  "initialize",
		Params:  map[string]interface{}{},
	}

	_, err := c.sendRequest(req)
	return err
}

// sendRequest 发送请求到MCP服务器
func (c *MCPClient) sendRequest(req MCPRequest) (*MCPResponse, error) {
	// 序列化请求
	data, err := json.Marshal(req)
	if err != nil {
		return nil, fmt.Errorf("序列化请求失败: %v", err)
	}

	// 发送请求
	_, err = c.stdin.Write(append(data, '\n'))
	if err != nil {
		return nil, fmt.Errorf("发送请求失败: %v", err)
	}

	// 读取响应
	line, err := c.reader.ReadString('\n')
	if err != nil {
		return nil, fmt.Errorf("读取响应失败: %v", err)
	}

	// 解析响应
	var resp MCPResponse
	if err := json.Unmarshal([]byte(line), &resp); err != nil {
		return nil, fmt.Errorf("解析响应失败: %v", err)
	}

	if resp.Error != nil {
		return nil, fmt.Errorf("MCP错误: %s", resp.Error.Message)
	}

	return &resp, nil
}

// GetTime 获取指定地点的时间
func (c *MCPClient) GetTime(ctx context.Context, location string) (string, error) {
	log.Printf("[MCP-CLIENT] 🕐 收到时间查询请求，地点: %s", location)
	
	if !c.isInit {
		log.Printf("[MCP-CLIENT] ⚠️ MCP客户端未初始化，正在启动...")
		if err := c.Start(); err != nil {
			log.Printf("[MCP-CLIENT] ❌ 启动MCP客户端失败: %v", err)
			return "", err
		}
	}

	c.mutex.Lock()
	defer c.mutex.Unlock()

	log.Printf("[MCP-CLIENT] 📤 发送时间查询请求到MCP服务器...")
	req := MCPRequest{
		JSONRPC: "2.0",
		ID:      time.Now().UnixNano(),
		Method:  "tools/call",
		Params: map[string]interface{}{
			"name": "get_time",
			"arguments": map[string]interface{}{
				"location": location,
			},
		},
	}

	resp, err := c.sendRequest(req)
	if err != nil {
		log.Printf("[MCP-CLIENT] ❌ 时间查询请求失败: %v", err)
		return "", err
	}

	log.Printf("[MCP-CLIENT] 📥 收到MCP服务器响应")

	// 解析结果
	if result, ok := resp.Result.(map[string]interface{}); ok {
		if content, ok := result["content"].([]interface{}); ok && len(content) > 0 {
			if item, ok := content[0].(map[string]interface{}); ok {
				if text, ok := item["text"].(string); ok {
					log.Printf("[MCP-CLIENT] ✅ 时间查询成功: %s", text)
					return text, nil
				}
			}
		}
	}

	log.Printf("[MCP-CLIENT] ❌ 无法解析时间查询结果: %+v", resp.Result)
	return "", fmt.Errorf("无法解析时间查询结果")
}

// Calculate 执行数学计算
func (c *MCPClient) Calculate(ctx context.Context, expression string) (string, error) {
	log.Printf("[MCP-CLIENT] 🧮 收到计算请求，表达式: %s", expression)
	
	if !c.isInit {
		log.Printf("[MCP-CLIENT] ⚠️ MCP客户端未初始化，正在启动...")
		if err := c.Start(); err != nil {
			log.Printf("[MCP-CLIENT] ❌ 启动MCP客户端失败: %v", err)
			return "", err
		}
	}

	c.mutex.Lock()
	defer c.mutex.Unlock()

	log.Printf("[MCP-CLIENT] 📤 发送计算请求到MCP服务器...")
	req := MCPRequest{
		JSONRPC: "2.0",
		ID:      time.Now().UnixNano(),
		Method:  "tools/call",
		Params: map[string]interface{}{
			"name": "calculate",
			"arguments": map[string]interface{}{
				"expression": expression,
			},
		},
	}

	resp, err := c.sendRequest(req)
	if err != nil {
		log.Printf("[MCP-CLIENT] ❌ 计算请求失败: %v", err)
		return "", err
	}

	log.Printf("[MCP-CLIENT] 📥 收到MCP服务器响应")

	// 解析结果
	if result, ok := resp.Result.(map[string]interface{}); ok {
		if content, ok := result["content"].([]interface{}); ok && len(content) > 0 {
			if item, ok := content[0].(map[string]interface{}); ok {
				if text, ok := item["text"].(string); ok {
					log.Printf("[MCP-CLIENT] ✅ 计算成功: %s", text)
					return text, nil
				}
			}
		}
	}

	log.Printf("[MCP-CLIENT] ❌ 无法解析计算结果: %+v", resp.Result)
	return "", fmt.Errorf("无法解析计算结果")
}

// AnalyzeUserIntent 分析用户意图
func (c *MCPClient) AnalyzeUserIntent(message string) (string, string) {
	log.Printf("[MCP-CLIENT] 🔍 开始分析用户意图，消息: %s", message)
	
	message = strings.ToLower(message)
	
	// 时间查询关键词
	timeKeywords := []string{"时间", "几点", "现在", "当前", "time", "clock"}
	locations := []string{"北京", "上海", "东京", "纽约", "伦敦", "巴黎", "洛杉矶", "悉尼", "新加坡", "香港", "台北", "首尔", "莫斯科", "迪拜", "孟买", "曼谷", "雅加达", "马尼拉", "吉隆坡", "河内"}
	
	// 计算关键词
	calcKeywords := []string{"计算", "算", "等于", "加", "减", "乘", "除", "平方根", "次方", "+", "-", "*", "/", "sqrt", "pow", "="}
	
	// 检查是否是时间查询
	hasTimeKeyword := false
	for _, keyword := range timeKeywords {
		if strings.Contains(message, keyword) {
			hasTimeKeyword = true
			log.Printf("[MCP-CLIENT] 🕐 检测到时间关键词: %s", keyword)
			break
		}
	}
	
	if hasTimeKeyword {
		for _, location := range locations {
			if strings.Contains(message, strings.ToLower(location)) {
				log.Printf("[MCP-CLIENT] 📍 检测到地点: %s，判断为时间查询", location)
				return "time", location
			}
		}
		// 如果有时间关键词但没有具体地点，默认查询北京时间
		log.Printf("[MCP-CLIENT] 🕐 有时间关键词但无具体地点，默认查询北京时间")
		return "time", "北京"
	}
	
	// 检查是否是计算请求
	for _, keyword := range calcKeywords {
		if strings.Contains(message, keyword) {
			expression := c.extractExpression(message)
			log.Printf("[MCP-CLIENT] 🧮 检测到计算关键词: %s，提取表达式: %s", keyword, expression)
			return "calculate", expression
		}
	}
	
	log.Printf("[MCP-CLIENT] 💬 未检测到特定意图，判断为普通聊天")
	return "chat", ""
}

// extractExpression 从消息中提取数学表达式
func (c *MCPClient) extractExpression(message string) string {
	// 移除常见的中文描述词
	message = strings.ReplaceAll(message, "计算", "")
	message = strings.ReplaceAll(message, "等于多少", "")
	message = strings.ReplaceAll(message, "是多少", "")
	message = strings.ReplaceAll(message, "？", "")
	message = strings.ReplaceAll(message, "?", "")
	message = strings.ReplaceAll(message, " ", "")
	
	// 替换中文运算符
	message = strings.ReplaceAll(message, "加", "+")
	message = strings.ReplaceAll(message, "减", "-")
	message = strings.ReplaceAll(message, "乘以", "*")
	message = strings.ReplaceAll(message, "乘", "*")
	message = strings.ReplaceAll(message, "除以", "/")
	message = strings.ReplaceAll(message, "除", "/")
	message = strings.ReplaceAll(message, "的平方根", "")
	message = strings.ReplaceAll(message, "平方根", "sqrt")
	message = strings.ReplaceAll(message, "的", "")
	message = strings.ReplaceAll(message, "次方", "")
	
	// 处理平方根
	if strings.Contains(message, "sqrt") && !strings.Contains(message, "(") {
		// 找到数字并包装成sqrt(number)
		for i, char := range message {
			if char >= '0' && char <= '9' {
				// 找到数字的结束位置
				j := i
				for j < len(message) && ((message[j] >= '0' && message[j] <= '9') || message[j] == '.') {
					j++
				}
				number := message[i:j]
				return fmt.Sprintf("sqrt(%s)", number)
			}
		}
	}
	
	// 处理幂运算 (如: 2的3次方 -> pow(2,3))
	if strings.Contains(message, "pow") || (strings.Contains(message, "的") && strings.Contains(message, "次方")) {
		// 简单的幂运算解析
		parts := strings.Split(message, "的")
		if len(parts) == 2 {
			base := strings.TrimSpace(parts[0])
			exp := strings.TrimSpace(strings.ReplaceAll(parts[1], "次方", ""))
			return fmt.Sprintf("pow(%s,%s)", base, exp)
		}
	}
	
	return strings.TrimSpace(message)
}
